<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="application/xhtml+xml;charset=utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <title>Ookii.CommandLine 2.1 user guide</title>
    <style type="text/css">
              body
              {
                  font-family: Calibri, "Trebuchet MS", Verdana, Arial, sans-serif;
                  margin: 3em;
                  max-width: 50em;
              }
              h1
              {
                  font-family: Cambria, 'Times New Roman', serif;
                  font-weight: normal;
                  color: #17365D;
                  border-bottom: solid 1px #418FBD;
              }
              h2
              {
                  font-size: large;
                  font-family: Cambria, 'Times New Roman', serif;
                  font-weight: bold;
                  color: #365F91;  
              }
              h3
              {
                  font-family: Cambria, 'Times New Roman', serif;
                  font-weight: bold;
                  color: #4F81BD;
                  font-size: 106%;
              }
              p
              {
                  margin: 0.5em 0;
                  padding: 0;
                  text-align: justify;
              }
              p.author
              {
                  font-family: Cambria, 'Times New Roman', serif;
                  font-style: italic;
                  color: #418FBD;
                  text-indent: 0;
              }
              a
              {
	              color: #00008B;
              }
              code
              {
                font-family: consolas, monospace;
                background-color: #D9D9D9;
              }
              pre
              {
                font-family: consolas, monospace;
                background-color: #E5E5E5;
                padding: 0.3em;
                margin-left: 3em;
              }
              .unknown
              {
                outline: solid 1px red;
                background-color: orange;
              }
              .code .lineNumber, .code td.lineNumbers
              {
	              color: #808080;
              }
              .code pre
              {
                  margin: 0;
              }
              .code td
              {
                  padding: 0;
              }
              .code td.lineNumbers
              {
                  text-align: right;
              }
              .code .keyword, .code .preprocessor
              {
	              color: #00F;
              }
              .code .operator
              {
	              color: #C63;
              }
              .code .comment
              {
	              color: #008000;
              }
              .code .xmlLiteral .comment
              {
	              color: #629755;
              }
              .code .string
              {
	              color: #A31515;
              }
              .code .entity
              {
	              color: #F00;
              }
              .code .tagDelimiter, .code .attributeDelimiter
              {
	              color: #00F;
              }
              .code .xmlLiteral .tagDelimiter, .code .xmlLiteral .attributeDelimiter, .code .xmlDelimiter, .code .xmlImportAttributeDelimiter
              {
	              color: #6464B9;
              }
              .code .tagName
              {
	              color: #A31515;
              }
              .code .xmlLiteral .tagName
              {
	              color: #844646;
              }
              .code .attributeName
              {
	              color: #F00;	
              }
              .code .xmlLiteral .attributeName, .code .xmlImportAttributeName
              {
	              color: #B96464;
              }
              .code .attributeValue
              {
	              color: #00F
              }
              .code .xmlLiteral .attributeValue, .code .xmlImportAttributeValue
              {
	              color: #6464B9;
              }
              .code .cdata
              {
	              color: #808080;
              }
              .code .xmlLiteral .cdata
              {
	              color: #C0C0C0;
              }
              .code .type
              {
	              color: #2B91AF;
              }
              .code .xmlLiteral .embeddedExpressionDelimiter
              {
	              color: #555;
	              background-color: #FFFEBF;
              }
              .code .sqlString
              {
	              color: #F00;
              }
              .code .sqlSystemFunction
              {
	              color: #F0F;
              }
              .code .sqlOperator
              {
	              color: #808080;
              }
              .code .psVariable
              {
                  color: #FF4511;
              }
              .code .psComment
              {
                  color: #006400;
              }
              .code .psString
              {
                  color: #8B0000;
              }
              .code .psOperator
              {
                  color: #A9A9A9
              }
              .code .psCommand
              {
                  color: #0000FF;
              }
              .code .psCommandParameter
              {
                  color: #000080;
              }
              .code .psCommandArgument
              {
                  color: #8D2BE2;
              }
              .code .psAttribute
              {
                  color: #ADD8E6;
              }
              .code .psNumber
              {
                  color: #800080;
              }
              .code .psType
              {
                  color: #008080;
              }
              .code .psKeyword, .code .psLoopLabel
              {
                  color: #26008B;
              }              
              
              @media print
              {
                  body
                  {
                      margin: 0;
                  }
              }
          </style>
  </head>
  <body>
    <h1>Ookii.CommandLine 2.2</h1>
    <p class="author">User Guide</p>
    <p>Copyright © Sven Groot (Ookii.org) 2013<br />For license information see license.txt</p>
    <h2>Introduction</h2>
    <p>Ookii.CommandLine is a library that helps you to parse command line arguments for your applications. It allows you to easily define a set of accepted arguments, and then parse the command line supplied to your application for those arguments. In addition, it allows you to generate usage help from the arguments that you defined which you can display to the user.</p>
    <p>Ookii.CommandLine can be used with any kind of .Net application, whether Console, Windows Forms, or WPF. Although a limited subset of functionality—particularly related around generating usage help text—is geared primarily towards console applications that are invoked from the command prompt, the main command line parsing functionality is usable in any application that needs to process command line arguments.</p>
    <p>To define a set of command line arguments, you create a class that will hold their values. The constructor parameters and properties of that class determine the set of arguments that are accepted. For each argument you can customize things like the argument name and whether or not an argument is required, and you can specify descriptions used to customize the usage help.</p>
    <p>Two samples are provided with the library, one for basic command line parsing and one for shell commands. Both have a C# and Visual Basic version so you can see how to use the Ookii.CommandLine library in your own code. Besides the source code, they are also included as binaries so you can experience how the argument parsing works by trying them out.</p>
    <h2>System requirements</h2>
    <p>Ookii.CommandLine 2.2 is a class library for use in your own applications. It can be used with applications targeting at least one of the following environments:</p>
    <ul>
      <li>
        <a href="http://msdn.microsoft.com/netframework">Microsoft .Net Framework</a> 2.0 or later</li>
      <li>
        <a href="http://www.mono-project.com/">Mono</a> 2.6 or later, using the .Net 2.0 or .Net 4.0 profile</li>
    </ul>
    <p>To view and edit the source code of Ookii.CommandLine or the included sample applications, you must use <a href="http://msdn.microsoft.com/vstudio">Microsoft Visual Studio 2010</a>. Because Ookii.CommandLine targets .Net 2.0, you can use the library with Visual Studio 2005 or later or any other development environment that targets .Net 2.0.</p>
    <h2>What’s new in Ookii.CommandLine 2.2</h2>
    <p>Ookii.CommandLine 2.2 offers the following improvements over version 2.1:</p>
    <ul>
      <li>Added support for alternative names (aliases) for command line arguments.</li>
      <li>An argument’s aliases and default value can be included in the argument description when generating usage.</li>
      <li>Added code snippets.</li>
    </ul>
    <p>Ookii.CommandLine 2.1 offers the following improvements over version 2.0:</p>
    <ul>
      <li>Added support for dictionary arguments; these are special multi-value arguments whose values take the form key=value.</li>
      <li>Multi-value arguments can be specified using a read-only property of any collection type (in addition to the previous array support).</li>
      <li>Multi-value properties can optionally use a separator character to allow multiple values to be specified without specifying the argument multiple times.</li>
      <li>Added support for specifying a custom type converter for individual arguments.</li>
      <li>When specifying the default value for an argument defined by a property you can now use any type that can be converted to the argument’s type using its type converter. This makes it possible to define default values for arguments with a type for which there are no literals.</li>
      <li>A CommandLineArgumentException is thrown when the argument type’s constructor or a property setter throws an exception (instead of a TargetInvocationException).</li>
      <li>The CommandLineParser no longer sets the property value for an unspecified argument with a default value of null.</li>
      <li>Shell commands can take their name from the type name.</li>
      <li>Shell commands can use custom argument parsing.</li>
      <li>Various minor bug fixes.</li>
    </ul>
    <p>Ookii.CommandLine 2.0 offers the following improvements compared to Ookii.CommandLine 1.0:</p>
    <ul>
      <li>Improved argument parsing:<ul><li>All arguments can be specified by name.</li><li>Support for using whitespace to separate an argument name from its value.</li><li>Support for multiple argument name prefixes.</li><li>Support for using a custom StringComparer for argument name matching (to allow case sensitive or insensitive matching).</li><li>Support for use a custom CultureInfo for argument value conversion.</li><li>Non-positional arguments can be required arguments.</li></ul></li>
      <li>Properties can be used to define positional arguments.</li>
      <li>More customizable generation of usage help text.</li>
      <li>The new shell commands functionality lets you easily create shell utilities with multiple operations that each uses its own command line arguments.</li>
      <li>The LineWrappingTextWriter class provides support for writing word-wrapped text to any output stream, with greater flexibility than the SplitLines method provided in Ookii.CommandLine 1.0.</li>
      <li>Targets .Net 2.0 for wider applicability.</li>
    </ul>
    <h3>Upgrading from Ookii.CommandLine 1.0</h3>
    <p>Ookii.CommandLine 2.0 and newer version have substantial changes from version 1.0 and are not designed to be backwards compatible. There are changes in argument parsing behavior and API names and usage.</p>
    <p>Upgrading an existing project that is using Ookii.CommandLine 1.0 to Ookii.CommandLine 2.0 or newer may require substantial code changes and may change how command lines are parsed.</p>
    <h2>Command line arguments</h2>
    <p>Command line arguments are passed to your application when it is started, and are typically accessed through the parameter of the <code>static v</code><code>oid Main(string[] args)</code> method (<code>S</code><code>hared S</code><code>ub Main(ByVal args() As String</code>) in Visual Basic). This provides with the arguments as an array of strings, which is not terribly useful. What Ookii.CommandLine allows you to do is to convert that array of strings into a strongly typed set of named values, which are stored in the properties of the class that was used to define the arguments.</p>
    <p>The method used to extract values from the array of string arguments is determined by the command line argument parsing rules. Ookii.CommandLine uses parsing rules that are very similar to how Microsoft PowerShell parses arguments for cmdlets, so if you have used PowerShell these rules will be familiar with you.</p>
    <p>Command line arguments follow the name of your application on the command prompt, and typically take the following form:</p>
    <pre>-ArgumentName ArgumentValue</pre>
    <p>The argument name is preceded by the <em>argument name prefix</em>. This prefix is configurable, but Ookii.CommandLine defaults to accepting a forward slash (<code>/</code>) and a dash (<code>-</code>) on Windows, and only a dash (<code>-</code>) on other platforms (other platforms are supported through Mono).</p>
    <p>The argument value follows the name, separated either by a space or a colon (<code>:</code>). Not all arguments require values; those that do not are called <em>switch arguments</em> and have a value determined by their presence or absence on the command line.</p>
    <p>An argument can have one or more aliases: alternative names that can also be used to specify the command name. For example, a parameter named “Verbose” might use the alias “v” as a shorter to type alternative.</p>
    <h3>Positional arguments</h3>
    <p>An argument can be <em>positional</em>, which means that its value can be specified either by name as indicated above, or by position. In this case the name of the argument is not required, and the argument’s value can be supplied by specifying it in the correct position in relation to other positional arguments.</p>
    <p>If an argument value is encountered without being preceded by a name, it is matched to the positional argument at the current position. For example, take the following command line arguments:</p>
    <pre>Value1 –ArgumentName Value2 Value3</pre>
    <p>In this case, Value1 is not preceded by a name; therefore it is matched to the first positional argument. Value2 follows a name, so it is matched to the argument with the name “ArgumentName”. Finally, Value3 is matched to the second positional argument.</p>
    <p>A positional argument can still be supplied by explicitly supplying its name. If a positional argument is supplied by name, it cannot also be specified by position; in the previous example, if the argument named “ArgumentName” was the second positional argument, then Value3 becomes the value for the third positional argument, because the value for “ArgumentName” was already specified by name.</p>
    <h3>Required arguments</h3>
    <p>A command line argument that is required must be present on all invocations of the application. If a required argument is not present, the <code>CommandLineParser</code> class will throw an exception during parsing.</p>
    <p>Any argument can be made required. Usually it is recommended for any required argument to also be a positional argument, but this is not necessary.</p>
    <p>For positional arguments, required arguments must always come before optional arguments; it is an error to define a required positional argument after an optional positional argument.</p>
    <h3>Arguments with multiple values</h3>
    <p>Some arguments can take multiple values; these are <em>multi-value arguments</em>, also known as <em>array arguments</em>. These arguments can be supplied multiple times, and each value is added to the set of values. For example, consider the following command line arguments:</p>
    <pre>-ArgumentName Value1 –ArgumentName Value2 –ArgumentName Value3</pre>
    <p>In this case, the value of the argument named “ArgumentName” will be a list holding all three values.</p>
    <p>The type of a multi-value argument must be an array type, for example <code>string[]</code> or <code>int[]</code> in C#, or any type implementing <code>ICollection&lt;T&gt;</code> when the argument is defined by a read-only property.</p>
    <p>It’s possible to specify a separator for multi-value arguments using the <code>MultiValueSeparatorAttribute</code> attribute. This makes it possible to specify multiple values for the argument while the argument itself is specified only once. For example, if the separator is set to a comma, you can specify the values as follows:</p>
    <pre>-ArgumentName Value1,Value2,Value3</pre>
    <p>In this case, the value of the argument named “ArgumentName” will be a list with the three values “Value1”, “Value2” and “Value3”.</p>
    <p>
      <strong>Note:</strong> if you specify a separator for a multi-value argument, it is <em>not</em> possible to have an argument value containing the separator. There is no way to escape the separator. Therefore, make sure you pick a separator that will never be used in the argument values, and be extra careful with culture-sensitive argument types (for example, if you use a comma as the separator for a multi-value argument of floating point numbers, cultures that use a comma as the decimal separator will not be able to specify values properly).</p>
    <p>If an argument is not a multi-value argument, it is an error to supply it more than once, unless duplicate arguments are allowed in which case only the last value is used.</p>
    <p>If a multi-value argument is positional, it must be the last positional argument. All remaining positional argument values will be considered values for the multi-value argument.</p>
    <p>If a multi-value argument is required, it means it must have at least one value.</p>
    <h3>Dictionary arguments</h3>
    <p>Dictionary arguments are multi-value arguments that specify a set of key/value pairs. Each value for a dictionary argument takes the form key=value, like in the following example:</p>
    <pre>-ArgumentName Key1=Value1 –ArgumentName Key2=Value2</pre>
    <p>In this case, the value of the argument named “ArgumentName” will be a dictionary with two keys, Key1 and Key2, with the associated values Value1 and Value2 respectively.</p>
    <p>A dictionary argument must have a type of <code>Dictionary&lt;TKey, TValue&gt;</code> where TKey and TValue are the types of the key and value. When using a read-only property to define the argument, you can use any type that implements <code>IDictionary&lt;TKey, TValue&gt;</code>.</p>
    <p>If you specify the same key more than once an exception will be thrown unless the <code>AllowDuplicateDictionaryKeysAttribute</code> attribute is specified on the constructor parameter or property that defines the dictionary argument.</p>
    <h3>Switch arguments</h3>
    <p>A switch argument is an argument with a Boolean type (<code>bool</code> in C#). Its value is determined by its presence or absence on the command line; the value will be true if the argument is supplied, and false if not. The following arguments set the switch argument named “switch” to true:</p>
    <pre>-switch</pre>
    <p>A switch argument’s value can be specified explicitly, as in the following example:</p>
    <pre>-switch:true</pre>
    <p>You must use a colon to specify an explicit value for a switch argument; you cannot use white space to separate the name and the value.</p>
    <p>If you use a nullable Boolean type (<code>bool?</code> In C#) as the type of the argument, it will be null if omitted, true if supplied, and false only if explicitly set to false using <code>-switch:false</code>.</p>
    <p>If the type of the argument is an array of Boolean values, it will act as a multi-value argument and a switch. A value of true (or the explicit value if one is given) gets added to the array for every time that the argument is supplied.</p>
    <h3>Argument value conversion</h3>
    <p>Ookii.CommandLine allows you to define arguments with any .Net type, including types such as <code>System.String</code>, <code>System.Int32</code>, <code>System.DateTime</code>, and many more. Any type can be used; the only requirement is that it is possible to convert a string value to that type.</p>
    <p>The .Net Framework provides a very flexible method for converting one type to another through the <code>System.ComponentModel.TypeConverter</code> class. You can use any type that has a type converter than can convert from a string for a command line argument. Most built-in types in .Net Framework have such a type converter. You can also use your own types by creating a type converter for that type.</p>
    <p>It is possible to override the default conversion by specifying a custom type converter using the <code>System.ComponentModel.TypeConverterAttribute</code>. When this attribute is applied to a constructor parameter or property that defines an argument, the specified type converter will be used for conversion instead. Note that for multi-value, dictionary and nullable value-type arguments the converter must be for the element type (e.g. if the argument is a multi-value argument of type <code>int[]</code>, the type converter must be able to convert to <code>int</code>). For a dictionary argument the element type is <code>KeyValuePair&lt;TKey, TValue&gt;</code>, and the type converter is responsible for parsing the key and value from the argument value.</p>
    <p>For many types, the conversion can be culture dependent. For example, converting numbers or dates depends on the culture which defines the accepted formats and how they’re interpreted; some cultures might use a period as the decimal separators, while others use a comma.</p>
    <p>The culture used for argument value conversions is specified the <code>CommandLineParser.Culture</code> property, which defaults to the current culture. If you wish your argument parsing to be independent of the user’s culture, set this property to <code>System.Globalization.CultureInfo.InvariantCulture</code>.</p>
    <h2>Defining command line arguments</h2>
    <p>In order to use Ookii.CommandLine, you must create a class that defines the arguments accepted by your application. This type will specify the names, types and attributes (required, positional) of each argument.</p>
    <p>There are two ways to define arguments: using the properties of the class, or using constructor parameters for the class.</p>
    <h3>Using properties</h3>
    <p>The preferred way to define arguments is by using properties. A property defines an argument only when it has the <code>CommandLineArgumentAttribute</code> attribute applied to it. The property must have a getter and setter, except for multi-value and dictionary arguments which can be defined by read-only properties under certain conditions.</p>
    <p>The type of the argument is the type of the property, and the name of the argument matches the property name by default, but this can be overridden using the <code>CommandLineArgumentAttribute</code> constructor.</p>
    <p>An argument defined by a property is by default optional and not positional. Its default value can be set using the <code>CommandLineArgumentAttribute.DefaultValue</code> property.</p>
    <p>To create a required argument, set the <code>CommandLineArgumentAttribute.IsRequired</code> property to true.</p>
    <p>To create a positional argument, set the <code>CommandLineArgumentAttribute.Position</code> property to a non-negative number. This property determines the relative ordering of the positional arguments only, not their actual position, so it’s fine if you skip numbers. Positional arguments defined by properties come after arguments defined by constructor parameters, so for example if there are three constructor parameters, the property with the lowest position value will be the fourth positional argument. Remember that you cannot have required positional arguments after optional ones, and that a multi-value positional argument must be the last positional argument. If your properties violate these rules, the <code>CommandLineParser</code> class’s constructor will throw an exception.</p>
    <p>To define a multi-value argument, you can use either a read-write property of an array type (e.g. <code>int[]</code>) or a read-only property of any type implementing <code>ICollection&lt;T&gt;</code> (e.g. <code>List&lt;int&gt;</code>).</p>
    <p>To define a dictionary argument, you can use either a read-write property of type <code>Dictionary&lt;TKey, TValue&gt;</code> (e.g. <code>Dictionary&lt;string, int&gt;</code>) or a read-only property of any type implementing <code>IDictionary&lt;TKey, TValue&gt;</code>.</p>
    <p>If the type of an argument is a Boolean, a nullable Boolean, or an array of Booleans, this defines a switch argument unless the argument is positional.</p>
    <p>Consider the following properties:</p>
    <pre class="code">[<span class="type">CommandLineArgument</span>(DefaultValue = <span class="string">"default"</span>)]
<span class="keyword">public</span> <span class="keyword">string</span> SomeArgument { <span class="keyword">get</span>; <span class="keyword">set</span>; }

[<span class="type">CommandLineArgument</span>(<span class="string">"OtherName"</span>, Position = 0)]
<span class="keyword">public</span> <span class="keyword">int</span> OtherArgument { <span class="keyword">get</span>; <span class="keyword">set</span>; }

[<span class="type">CommandLineArgument</span>]
<span class="keyword">public</span> <span class="keyword">bool</span> Switch { <span class="keyword">get</span>; <span class="keyword">set</span>; }

<span class="keyword">public</span> <span class="keyword">string</span> NotAnArgument { <span class="keyword">get</span>; <span class="keyword">set</span>; }</pre>
    <p>The first property defines an optional non-positional argument of type string with the name “SomeArgument” and the default value “default”.</p>
    <p>The second property defines an optional positional argument of type int with the name “OtherName”. The argument will be the first positional argument (after the arguments defined by constructor parameters, if there are any).</p>
    <p>The third property defines a switch argument, because its type is a Boolean. Switch arguments can be supplied without a value; they will be true if present and false is not.</p>
    <p>The fourth property does not define an argument, because it doesn’t have the <code>CommandLineArgumentAttribute</code> applied.</p>
    <h3>Using constructor parameters</h3>
    <p>An alternative way to define positional parameters is using a constructor. The parameters of the public constructor for the class that defines the arguments will be used to define arguments. These arguments will be positional arguments, and required if the parameter is a required parameter.</p>
    <p>Every constructor parameter creates a positional argument with its position matching the position of the constructor parameter. The type of the constructor parameter is the type of the argument, and by default the name of the constructor parameter is used of as the argument name, but this can be overridden using the <code>ArgumentNameAttribute</code> attribute.</p>
    <p>For example, consider a class with the following constructor:</p>
    <pre class="code"><span class="keyword">public</span> MyArguments(<span class="keyword">string</span> arg1,
                   <span class="keyword">int</span> arg2,
                   [<span class="type">ArgumentName</span>(<span class="string">"CustomName"</span>)] <span class="keyword">float</span> arg3 = 0f)
{
}</pre>
    <p>This constructor defines the following arguments: a required positional argument of type <code>string</code> with the name “arg1”, a required positional argument of type <code>int</code> with the name “arg3”, and an optional positional argument of type <code>float</code> with the name “CustomName” and a default value of 0.</p>
    <p>If you are not using the C# 4.0 compiler, you can apply the <code>System.Runtime.InteropServices.OptionalAttribute</code> attribute and the <code>System.Runtime.InteropServices.DefaultParameterValueAttribute</code> to the parameter to define an optional argument. In Visual Basic, you can use the usual syntax for optional parameters (for an example, see the source code of the Visual Basic sample application included with the library).</p>
    <p>If the type of a constructor parameter is an array, this defines a multi-value positional argument.</p>
    <p>If your type has more than one constructor, you must mark one of them using the <code>CommandLineConstructorAttribute</code> attribute. You don’t need to use this attribute if you have only one constructor.</p>
    <p>If you don’t wish to define arguments using the constructor, simply use a constructor without any parameters (or don’t define an explicit constructor).</p>
    <h3>Defining aliases</h3>
    <p>An alias is an alternative name that can be used to specify a command line argument. Aliases can be added to a command line argument by applying the <code>AliasAttribute</code> to the property or constructor parameter that defines the argument.</p>
    <p>For example, the following code defines a switch argument that can be specified using either the name “Verbose” or the alias “v”:</p>
    <pre class="code">[<span class="type">CommandLineArgument</span>, <span class="type">Alias</span>(<span class="string">"v"</span>)]
<span class="keyword">public</span> <span class="keyword">bool</span> Verbose { <span class="keyword">get</span>; <span class="keyword">set</span>; }</pre>
    <p>To specify more than one alias for an argument, simply apply the <code>AliasAttribute</code> multiple times.</p>
    <h2>Parsing command line arguments</h2>
    <p>When you have defined the command line arguments, you can now parse the command line to determine the argument values.</p>
    <p>In order to do this, you first must create an instance of the <code>CommandLineParser</code> class, passing the type of the class that defines the parameters to the constructor. Then call the <code>CommandLineParser.Parse</code> method, passing the arguments your application received.</p>
    <p>If argument parsing is successful, the <code>CommandLineParser.Parse</code> method will create a new instance of the class defining the arguments, passing the values parsed from the command line to the constructor parameters (if any). It will then set the value of each property to the value of the corresponding argument. This is not done in any particular order, so do not write code that makes assumptions about this. Finally, it will return this instance.</p>
    <p>If argument parsing fails, the <code>CommandLineParser.Parse</code> method will throw a <code>CommandLineArgumentException</code> exception. Argument parsing can fail because not all required arguments were specified, an argument name was supplied without a value for an argument that’s not a switch, an unknown argument name was supplied, a non-multi-value argument was specified more than once, too many positional argument values were supplied, or argument value conversion failed for one of the arguments. Check the <code>CommandLineParser.Category</code> property to determine the cause of the exception.</p>
    <p>A typical usage sample for the <code>CommandLineParser</code> class is as follows:</p>
    <pre class="code"><span class="keyword">static</span> <span class="keyword">void</span> Main(<span class="keyword">string</span>[] args)
{
    <span class="type">CommandLineParser</span> parser = <span class="keyword">new</span> <span class="type">CommandLineParser</span>(<span class="keyword">typeof</span>(<span class="type">MyArguments</span>));
    <span class="keyword">try</span>
    {
        <span class="type">MyArguments</span> arguments = (<span class="type">MyArguments</span>)parser.Parse(args);
        RunApplication(arguments);
    }
    <span class="keyword">catch</span>( <span class="type">CommandLineArgumentException</span> ex )
    {
        <span class="type">Console</span>.WriteLine(ex.Message);
        parser.WriteUsageToConsole();
    }
}</pre>
    <p>This sample tries to parse the arguments, and if it fails prints the error message and usage help to the console.</p>
    <p>The <code>CommandLineParser</code> class provides several ways to customize the parsing behavior; check the class library documentation for more details.</p>
    <h2>Generating usage help</h2>
    <p>When you have an application that accepts command line arguments, it’s often useful to be able to provide the user with information about how to invoke the application, including an overview of all the arguments.</p>
    <p>Creating this kind of usage help text is tedious, and you must make sure it is kept up to date whenever you change the arguments to your application. For this reason, Ookii.CommandLine can generate this usage help text automatically. The generated usage help can be customized by adding descriptions to the arguments.</p>
    <p>Usage help can be generated using the <code>CommandLineParser.WriteUsage</code> method. The output can be customized using the <code>WriteUsageOptions</code> class. The <code>CommandLineParser.WriteUsageToConsole</code> method provides a convenient way to write the usage help to the standard output stream, properly word-wrapping the text at the console width.</p>
    <p>The following example shows the usage help generated for the sample application included with the Ookii.CommandLine library:</p>
    <pre>Sample command line application. The application parses the command<br />line and prints the results, but otherwise does nothing, and none<br />of the arguments are actually used for anything.<br /><br />Usage: CommandLineSampleCS.exe [-source] &lt;String&gt; <br />   [-destination] &lt;String&gt; [[-index] &lt;Number&gt;] [[-id] &lt;String&gt;] [-?]<br />   [-Count &lt;Number&gt;] [-Date &lt;DateTime&gt;] [-v] [-val &lt;String&gt;...]<br /><br />    -source &lt;String&gt;<br />        The source data.<br /><br />    -destination &lt;String&gt;<br />        The destination data.<br /><br />    -index &lt;Number&gt;<br />        The operation's index. This argument is optional, and the<br />        default value is 1.<br /><br />    -id &lt;String&gt;<br />        Sets the operation ID. The default value is "default".<br /><br />    -? [&lt;Boolean&gt;]<br />        Displays this help message.<br /><br />    -Count &lt;Number&gt;<br />        Provides the count for something to the application. This<br />        argument is required.<br /><br />    -Date &lt;DateTime&gt;<br />        Provides a date to the application; the format to use<br />        depends on your regional settings.<br /><br />    -v [&lt;Boolean&gt;]<br />        Print verbose information; this is an example of a switch<br />        argument.<br />    -val &lt;String&gt;<br />        This is an example of an array argument, which can be<br />        repeated multiple times to set more than one value.</pre>
    <p>The usage help consists of three components: the application description, the argument syntax, and the argument descriptions.</p>
    <h3>Application description</h3>
    <p>The first part of the usage help is a description of your application. This is a short description that explains what your application does and how it can be used. It can be any text you like, though it’s recommended to keep it short.</p>
    <p>The description is specified by specifying the <code>System.ComponentModel.DescriptionAttribute</code> to the class that defines the command line arguments, as in the following example:</p>
    <pre class="code">[<span class="type">Description</span>(<span class="string">"This is the application description that is included in the usage help."</span>)]
<span class="keyword">class</span> <span class="type">MyArguments</span>
{
}</pre>
    <p>If this attribute is not specified, no description is included in the usage help. The description can also be omitted by setting the <code>WriteUsageOptions.IncludeApplicationDescription</code> property to false.</p>
    <h3>Argument syntax</h3>
    <p>The argument syntax indicates how your application can be invoked from the command line. The argument syntax typically starts with the name of your application, and is followed by all the arguments, indicating their name and type. There is an indication of which arguments are required or optional, and whether they allow multiple values. For positional arguments, the order is indicated as well.</p>
    <p>The syntax for a single argument has the following format:</p>
    <pre>-ArgumentName &lt;ValueDescription&gt;</pre>
    <p>For optional arguments, the name and value description are enclosed by square brackets. For a positional argument, the name is enclosed by square brackets to indicate the name itself is optional. For an array argument, the value description is followed by three periods.</p>
    <p>The value description of an argument is short description (typically one word) that describes what kind of value the argument expects. It default to the type of the argument (for array arguments, the element type is used; for nullable types, the underlying type is used).</p>
    <p>The value description can be specified explicitly. For example, you may want to set the value description of a numeric argument to “Number” rather than “Int32”. For arguments defined using constructor parameters, use the <code>ValueDescriptionAttribute</code> attribute. For arguments defined by a property, use the <code>CommandLineArgumentAttribute.ValueDescription</code> property.</p>
    <p>The value description is omitted for switch arguments.</p>
    <p>The exact format of the argument syntax can be customized using the <code>WriteUsageOptions</code> class. You can specify the usage prefix, and various format strings that control how optional arguments, value descriptions, and multi-value arguments are displayed.</p>
    <h3>Argument descriptions</h3>
    <p>The final part of the usage help is a description for all the arguments. A list is written to the output of all arguments, followed by their description.</p>
    <p>The description of an argument can be specified using the <code>System.ComponentModel.DescriptionAttribute</code> attribute. Apply this attribute to the constructor parameter or property defining the argument.</p>
    <p>The exact format of the argument descriptions can be customized using the <code>WriteUsageOptions</code> class. You can specify a format string that controls how the argument name and description are laid out, and the amount of indentation to use for additional lines of the description.</p>
    <p>By default, the default value and aliases of an argument are not included in the argument syntax or description. If you wish to advertise these to the user, you can add them in the argument’s description itself, or set the <code>WriteUsageOptions.IncludeDefaultValueInDescription</code> and <code>WriteUsageOptions.IncludeAliasInDescription</code> properties to true.</p>
    <h2>Shell commands</h2>
    <p>Ookii.CommandLine provides the ability to create an application that has more than one function by using shell commands.</p>
    <p>Shell commands can be used to create shell utilities that perform more than one operation, where each operation has its own set of command line arguments. For example, a utility might be used to modify or query different configuration parameters of a system. Depending on whether it's a query or a modification, and which configuration parameter is used, the arguments to such a utility might differ. Rather than provide different executables for each operation, it is often more convenient to combine related operations in a single utility.</p>
    <p>Think for example of the Windows <code>net</code> command, which provides many different operations through the same command. Shell commands allow you to easily create such an application.</p>
    <p>For a program using shell commands, typically the first command line argument will be the name of the operation and identifies which shell command to use, while the remaining arguments are arguments to the command. The <code>ShellCommand</code> class aids you in creating utilities that follow this pattern. </p>
    <p />
    <h3>Defining shell commands</h3>
    <p>A shell command is created by deriving a type from the <code>ShellCommand</code> class, specifying the <code>ShellCommandAttribute</code> on that type to specify the name of the command, and implementing the <code>ShellCommand.Run</code> method for that type.</p>
    <p>The class inheriting the <code>ShellCommand</code> class defines the arguments for the command. This class will be used with the <code>CommandLineParser</code> class to parse the arguments for the command.</p>
    <h3>Using shell commands</h3>
    <p>To use a shell command, you must first determine the shell command the user wishes to invoke, typically by inspecting the first element of the array of arguments passed to the <code>Main</code> method of your application.</p>
    <p>You can then get the <code>Type</code> instance of the shell command’s class by calling the <code>ShellCommand.GetShellCommand</code> method. This method searches the specified assembly for a type that inherits from the <code>ShellCommand</code> class, and has the <code>ShellCommandAttribute</code> attribute applied with the <code>ShellCommandAttribute.Name</code> property set to the specified name. You can also get a list of all shell commands in an assembly by using the <code>ShellCommand.GetShellCommands</code> method.</p>
    <p>This <code>Type</code> instance can be passed to the constructor of the <code>CommandLineParser</code> class, after which you can parse arguments for the command as usual (make sure to pass an index so that the command name is not treated as an argument), and finally invoke its <code>ShellCommand.Run</code> method.</p>
    <p>The <code>ShellCommand</code> class provides static utility methods that perform these tasks for you. The <code>ShellCommand.CreateShellCommand</code> method finds and creates a shell command, and writes error and usage information to the output if it failed. If no command name was specified, or the specified command name could not be found, it writes a list of all shell commands in the assembly and their descriptions to the output. If the command was found but parsing its arguments failed, it writes usage information for that command to the output.</p>
    <p>The <code>ShellCommand.RunShellCommand</code> method works the same as the <code>ShellCommand.CreateShellCommand</code> method, but also invokes the <code>ShellCommand.Run</code> method if the command was successfully created.</p>
    <p>It is recommended to return the value of the <code>ShellCommand.ExitCode</code> property to the operating system (by returning it from the <code>Main</code> method or by using the <code>Environment.</code><code>ExitCode</code> property) after running the shell command. </p>
    <p>The source code of a full sample application that defines two commands is included with the Ookii.CommandLine library.</p>
    <h2>Line wrapping text writer</h2>
    <p>The Ookii.CommandLine library includes a utility class, the <code>LineWrappingTextWriter</code> class, which it uses for properly word-wrapping usage help when writing it to the console, but which can also be used in your own code.</p>
    <p>The <code>LineWrappingTextWriter</code> class allows you to write text to another <code>TextWriter</code> class, wrapping that text at the specified line length, and optionally indenting subsequent lines.</p>
    <p />
  </body>
</html>